home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
comm
/
term
/
term34Source.lha
/
termStatusDisplay.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
46KB
|
2,053 lines
/*
** termStatusDisplay.c
**
** Status information display routines
**
** Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* The information to be displayed. */
enum { INFO_STATUS,INFO_FONT,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST };
/* The current status line display mode. */
enum { MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,MODE_WB_NORMAL,MODE_WB_COMPRESSED };
/* Enumerated text boxes. */
enum { STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE };
/* The tags our private status gadget class responds to. */
#define SG_Status (TAG_USER+1)
#define SG_Font (TAG_USER+2)
#define SG_Protocol (TAG_USER+3)
#define SG_Emulation (TAG_USER+4)
#define SG_BaudRate (TAG_USER+5)
#define SG_Parameters (TAG_USER+6)
#define SG_CurrentTime (TAG_USER+7)
#define SG_OnlineTime (TAG_USER+8)
#define SG_OnlineCost (TAG_USER+9)
/* Special private information maintained and required
* by the status gadget class.
*/
struct StatusInfo
{
struct TextBox *BoxArray[4],
*BoxList;
LONG FullWidth;
LONG FirstColumn;
UWORD Mask;
UWORD Mode;
LONG LastWidth;
UBYTE Strings[8][20];
struct SignalSemaphore Semaphore;
LONG WindowWidth,
WindowHeight,
WindowFlags;
};
/* The status server passes this structure to the
* rendering routine if the status information
* is to be updated.
*/
struct ObjectCarrier
{
struct RastPort *RPort;
struct TextBox **BoxArray;
};
/* A custom message type for the display update server. */
struct UpdateMessage
{
struct Message VanillaMessage;
APTR Object;
UBYTE Mode,
Type;
};
/* The following static strings are displayed in the status
* window.
*/
STATIC STRPTR ConfigFont[3],
ConfigEmulation[6],
ConfigParity[6],
ConfigStatus[8];
/* Width of the status line text, required in case the user interface
* font happens to be proportional-spaced.
*/
STATIC LONG StatusLineWidth;
/* Our local private status gadget class. */
STATIC struct IClass *StatusGadgetClass;
/* The status display update task. */
STATIC struct Task *StatusDisplayTask;
STATIC struct MsgPort *StatusDisplayPort;
/* Prototypes for this module. */
STATIC ULONG SetStatusGadget(struct IClass *class,Object *object,struct opSet *SetInfo);
STATIC ULONG GetStatusGadget(struct IClass *class,Object *object,struct opGet *GetInfo);
STATIC ULONG RenderStatusGadget(struct IClass *class,Object *object,struct gpRender *RenderInfo);
STATIC ULONG DelStatusGadget(struct IClass *class,Object *object,Msg msg);
STATIC ULONG NewStatusGadget(struct IClass *class,Object *object,struct opSet *SetMethod);
STATIC ULONG __saveds __asm StatusGadgetDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg);
STATIC VOID FreeStatusGadgetClass(VOID);
STATIC BYTE NewStatusGadgetClass(VOID);
/* GetStatusGadget():
*
* Query information on the status gadget.
*/
STATIC ULONG
GetStatusGadget(struct IClass *class,Object *object,struct opGet *GetInfo)
{
struct StatusInfo *StatusInfo = INST_DATA(class,object);
switch(GetInfo -> opg_AttrID)
{
case SGA_FullWidth:
*GetInfo -> opg_Storage = (ULONG)StatusInfo -> FullWidth;
return(1);
default:
return(DoSuperMethodA(class,object,(Msg)GetInfo));
}
}
/* SetStatusGadget():
*
* Set certain attributes of the status gadget.
*/
STATIC ULONG
SetStatusGadget(struct IClass *class,Object *object,struct opSet *SetInfo)
{
struct StatusInfo *StatusInfo = INST_DATA(class,object);
LONG i,j;
struct RastPort *RPort;
struct TagItem *Tag;
DoSuperMethodA(class,object,(Msg)SetInfo);
/* Make sure that the information is available and
* nobody else tries to modify it.
*/
ObtainSemaphore(&StatusInfo -> Semaphore);
/* Obtain the new text to be displayed in the gadget. */
for(i = SG_Status, j = 0 ; i <= SG_OnlineCost ; i++, j++)
{
if(Tag = FindTagItem(i,SetInfo -> ops_AttrList))
{
strcpy(StatusInfo -> Strings[j],(STRPTR)Tag -> ti_Data);
StatusInfo -> Mask |= (1 << j);
}
}
/* Release the lock. */
ReleaseSemaphore(&StatusInfo -> Semaphore);
/* Kluge! */
if(Kick30)
return(1);
/* Obtain the drawing area lock. */
if(RPort = ObtainGIRPort(SetInfo -> ops_GInfo))
{
/* Normal, uncompressed status line? */
if(StatusInfo -> Mode == MODE_WB_NORMAL)
{
/* Take a look at the strings which have
* changed and render the corresponding
* text.
*/
for(i = 0 ; i < 8 ; i++)
{
if(StatusInfo -> Mask & (1 << i))
{
SZ_SetLine(RPort,StatusInfo -> BoxArray[i / 2],i % 2,StatusInfo -> Strings[i]);
StatusInfo -> Mask &= ~(1 << i);
}
}
}
else
{
STATIC BYTE Offsets[8] =
{
0,
-1,
26,
11,
40,
53,
61,
72
};
struct Gadget *Gadget;
UBYTE LineBuffer[90];
WORD i,j,k;
LONG Width,
Left,
Top;
/* Get the real gadget. */
Gadget = (struct Gadget *)object;
/* Fill the line with defaults. */
strcpy(LineBuffer," · · · · · · ");
/* Add the information strings. */
for(i = 0 ; i < 8 ; i++)
{
if(Offsets[i] >= 0)
{
j = strlen(StatusInfo -> Strings[i]);
for(k = 0 ; k < j ; k++)
LineBuffer[Offsets[i] + k] = StatusInfo -> Strings[i][k];
}
}
/* Determine the pixel width of the string. */
Width = TextLength(RPort,LineBuffer,80);
/* Get the rendering top offset. */
Top = SetInfo -> ops_GInfo -> gi_Window -> Height + Gadget -> TopEdge;
SetDrMd(RPort,JAM2);
/* Are we to clear the area the last rendering
* operation obscured?
*/
if(StatusInfo -> LastWidth && StatusInfo -> LastWidth != Width)
{
Left = (SetInfo -> ops_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2;
/* Set the approriate rendering pen. */
if(SetInfo -> ops_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
else
SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
/* Clear the area. */
RectFill(RPort,Left,Top,Left + StatusInfo -> LastWidth - 1,Top + Gadget -> Height - 3);
}
/* Set the approriate rendering pens. */
if(SetInfo -> ops_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
{
SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN]);
SetBPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
}
else
{
SetAPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN]);
SetBPen(RPort,SetInfo -> ops_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
}
/* Remember the text pixel width. */
StatusInfo -> LastWidth = Width;
/* Display the status line. */
Move(RPort,(SetInfo -> ops_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2,Top + RPort -> Font -> tf_Baseline);
Text(RPort,LineBuffer,80);
}
/* Release the rendering area. */
ReleaseGIRPort(RPort);
}
return(1);
}
/* RenderStatusGadget():
*
* Redraw the entire status gadget.
*/
STATIC ULONG
RenderStatusGadget(struct IClass *class,Object *object,struct gpRender *RenderInfo)
{
struct StatusInfo *StatusInfo = INST_DATA(class,object);
struct RastPort *RPort = RenderInfo -> gpr_RPort;
BYTE MustRender,
UpdateOnly;
ULONG Width = RenderInfo -> gpr_GInfo -> gi_Window -> Width,
Height = RenderInfo -> gpr_GInfo -> gi_Window -> Height,
Flags = RenderInfo -> gpr_GInfo -> gi_Window -> Flags;
LONG i;
/* Kluge! */
if(Kick30)
{
if(StatusInfo -> Mask)
UpdateOnly = MustRender = TRUE;
else
UpdateOnly = MustRender = FALSE;
if(StatusInfo -> WindowWidth != Width || StatusInfo -> WindowHeight != Height || ((Flags & WFLG_WINDOWACTIVE) != StatusInfo -> WindowFlags))
{
MustRender = TRUE;
UpdateOnly = FALSE;
StatusInfo -> WindowWidth = Width;
StatusInfo -> WindowHeight = Height;
StatusInfo -> WindowFlags = Flags & WFLG_WINDOWACTIVE;
StatusInfo -> Mask = 0xFF;
}
}
else
{
UpdateOnly = MustRender = TRUE;
StatusInfo -> Mask |= 0xFF;
}
if(MustRender)
{
/* Normal, uncompressed display? */
if(StatusInfo -> Mode == MODE_WB_NORMAL)
{
/* Refresh the entire imagery (the default)? */
if(RenderInfo -> gpr_Redraw == GREDRAW_REDRAW && !UpdateOnly)
{
struct Gadget *Gadget = (struct Gadget *)object;
LONG X;
/* Don't let anyone modify the text. */
ObtainSemaphore(&StatusInfo -> Semaphore);
/* Get the new gadget left offset. */
if((X = (RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> FullWidth) / 2) < 0)
X = 0;
X += StatusInfo -> FirstColumn - SZ_GetBoxInfo(StatusInfo -> BoxList,BOX_LEFT);
/* Move the status line to the new location. */
SZ_SetBoxes(StatusInfo -> BoxList,-1,RenderInfo -> gpr_GInfo -> gi_Window -> Height + Gadget -> TopEdge + 1);
if(X)
SZ_MoveBoxes(StatusInfo -> BoxList,X,0);
/* Set the box title rendering pen. */
if(Flags & WFLG_WINDOWACTIVE)
SZ_SetTitlePen(StatusInfo -> BoxList,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN],RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
else
SZ_SetTitlePen(StatusInfo -> BoxList,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN],RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
/* Redraw the boxes. */
SZ_DrawBoxes(RPort,StatusInfo -> BoxList);
/* Redraw all the strings. */
ReleaseSemaphore(&StatusInfo -> Semaphore);
}
/* Update the information which has changed. */
for(i = 0 ; i < 8 ; i++)
{
if(StatusInfo -> Mask & (1 << i))
{
SZ_SetLine(RPort,StatusInfo -> BoxArray[i / 2],i % 2,StatusInfo -> Strings[i]);
StatusInfo -> Mask &= ~(1 << i);
}
}
}
else
{
STATIC BYTE Offsets[8] =
{
0,
-1,
26,
11,
40,
53,
61,
72
};
struct Gadget *Gadget;
UBYTE LineBuffer[90];
WORD i,j,k;
LONG Width,
Left,
Top;
/* Grab the access semaphore. */
ObtainSemaphore(&StatusInfo -> Semaphore);
/* Get the real gadget info. */
Gadget = (struct Gadget *)object;
/* Fill the line buffer with defaults. */
strcpy(LineBuffer," · · · · · · ");
/* Fill in the information strings. */
for(i = 0 ; i < 8 ; i++)
{
if(Offsets[i] >= 0)
{
j = strlen(StatusInfo -> Strings[i]);
for(k = 0 ; k < j ; k++)
LineBuffer[Offsets[i] + k] = StatusInfo -> Strings[i][k];
}
}
/* Determine the pixel width of the line. */
Width = TextLength(RPort,LineBuffer,80);
/* Get the line top offset. */
Top = RenderInfo -> gpr_GInfo -> gi_Window -> Height + Gadget -> TopEdge;
SetDrMd(RPort,JAM2);
/* Clear the previously written text if necessary. */
if(StatusInfo -> LastWidth && RenderInfo -> gpr_Redraw != GREDRAW_REDRAW)
{
Left = (RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2;
if(RenderInfo -> gpr_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
else
SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
RectFill(RPort,Left,Top,Left + StatusInfo -> LastWidth - 1,Top + Gadget -> Height - 3);
}
/* Set the approriate rendering colours. */
if(RenderInfo -> gpr_GInfo -> gi_Window -> Flags & WFLG_WINDOWACTIVE)
{
SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLTEXTPEN]);
SetBPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[FILLPEN]);
}
else
{
SetAPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[TEXTPEN]);
SetBPen(RPort,RenderInfo -> gpr_GInfo -> gi_DrInfo -> dri_Pens[BACKGROUNDPEN]);
}
/* Remember last pixel width. */
StatusInfo -> LastWidth = Width;
/* Render the status line. */
Move(RPort,(RenderInfo -> gpr_GInfo -> gi_Window -> Width - StatusInfo -> LastWidth) / 2,Top + RPort -> Font -> tf_Baseline);
Text(RPort,LineBuffer,80);
/* Release the lock. */
ReleaseSemaphore(&StatusInfo -> Semaphore);
}
}
return(0);
}
/* DelStatusGadget():
*
* Deallocate the status gadget.
*/
STATIC ULONG
DelStatusGadget(struct IClass *class,Object *object,Msg msg)
{
struct StatusInfo *StatusInfo = INST_DATA(class,object);
if(StatusInfo -> BoxList)
SZ_FreeBoxes(StatusInfo -> BoxList);
return(DoSuperMethodA(class,object,msg));
}
/* NewStatusGadget():
*
* Create a new status gadget.
*/
STATIC ULONG
NewStatusGadget(struct IClass *class,Object *object,struct opSet *SetMethod)
{
struct Gadget *NewGadget;
struct TagItem *OldTags,*Item;
LONG NewItems[5][2],
Height,
Mode;
/* Remember the old tag item list, as we will change it. */
OldTags = SetMethod -> ops_AttrList;
/* Determine the status line mode (compressed or normal). */
if(Item = FindTagItem(SGA_Mode,OldTags))
{
switch(Item -> ti_Data)
{
case MODE_WB_NORMAL:
case MODE_WB_COMPRESSED:
Mode = Item -> ti_Data;
break;
default:
return(NULL);
}
}
else
return(NULL);
/* Set up the defaults, note that this class
* implementation can, strictly speaking, not
* be considered reentrant.
*/
SZ_SizeSetup(DefaultPubScreen,&UserFont,TRUE);
/* Determine object height. */
if(Mode == MODE_WB_NORMAL)
Height = 3 + SZ_BoxHeight(2);
else
Height = 2 + UserFontHeight;
/* Build new tag item list. */
NewItems[0][0] = GA_RelBottom;
NewItems[0][1] = -Height;
NewItems[1][0] = GA_Height;
NewItems[1][1] = Height;
NewItems[2][0] = GA_BottomBorder;
NewItems[2][1] = TRUE;
NewItems[3][0] = GA_Highlight;
NewItems[3][1] = GFLG_GADGHNONE;
NewItems[4][0] = TAG_MORE;
NewItems[4][1] = (LONG)OldTags;
/* Install the new tag item list. */
SetMethod -> ops_AttrList = (struct TagItem *)NewItems;
/* Create the new object. */
if(NewGadget = (struct Gadget *)DoSuperMethodA(class,object,(Msg)SetMethod))
{
struct StatusInfo *StatusInfo = INST_DATA(class,NewGadget);
LONG SizeGadgetWidth;
StatusInfo -> WindowWidth = StatusInfo -> WindowHeight = 0;
/* Determine the width of the window sizing gadget,
* hopefully these values are never going to be
* changed.
*/
if(DefaultPubScreen -> Flags & SCREENHIRES)
SizeGadgetWidth = SIZE_GADGET_WIDTH_HIGH;
else
SizeGadgetWidth = SIZE_GADGET_WIDTH_LOW;
/* Clear the extra information area. */
memset(StatusInfo,0,sizeof(struct StatusInfo));
/* Initialize the signal semaphore. */
InitSemaphore(&StatusInfo -> Semaphore);
/* Is it the `big one'? */
if((StatusInfo -> Mode = Mode) == MODE_WB_NORMAL)
{
WORD ColumnLeft[4],
ColumnWidth[4];
struct TextBox *Box;
LONG i,Max = 0,Len,FullWidth,BoxCounter = 0;
ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
for(i = 0 ; ConfigStatus[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
Max = Len;
}
for(i = 0 ; ConfigFont[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigFont[i]))) > Max)
Max = Len;
}
ColumnWidth[0] = Max;
Max = SZ_BoxWidth(12);
for(i = 0 ; ConfigEmulation[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
Max = Len;
}
ColumnWidth[1] = Max;
Max = SZ_BoxWidth(10);
for(i = 0 ; ConfigParity[i] ; i++)
{
if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
Max = Len;
}
ColumnWidth[2] = Max;
ColumnWidth[3] = SZ_BoxWidth(8);
FullWidth = 0;
for(i = 0 ; i < 4 ; i++)
FullWidth += ColumnWidth[i] + ColumnLeft[i];
FullWidth += 3 * InterWidth;
StatusInfo -> FullWidth = FullWidth + 2 * SizeGadgetWidth;
StatusInfo -> FirstColumn = ColumnLeft[0];
if(FullWidth > DefaultPubScreen -> Width)
SZ_SetLeftEdge(ColumnLeft[0]);
else
SZ_SetLeftEdge((DefaultPubScreen -> Width - FullWidth) / 2 + ColumnLeft[0]);
SZ_SetAbsoluteTop(2);
SZ_SetTopEdge(2);
SZ_SetWidth(ColumnWidth[0]);
StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
SZ_SetWidth(ColumnWidth[1]);
SZ_AddLeftOffset(ColumnLeft[1]);
StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
SZ_SetWidth(ColumnWidth[2]);
SZ_AddLeftOffset(ColumnLeft[2]);
StatusInfo -> BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
SZ_SetWidth(ColumnWidth[3]);
SZ_AddLeftOffset(ColumnLeft[3]);
StatusInfo -> BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&StatusInfo -> BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
if(!Box)
{
SZ_FreeBoxes(StatusInfo -> BoxList);
DoSuperMethod(class,(Object *)NewGadget,OM_DISPOSE);
NewGadget = NULL;
}
}
else
StatusInfo -> FullWidth = SZ_BoxWidth(80) + 2 * SizeGadgetWidth;
}
/* Install the old tag item list. */
SetMethod -> ops_AttrList = OldTags;
return((ULONG)NewGadget);
}
/* StatusGadgetDispatch():
*
* Dispatch an object message.
*/
STATIC ULONG __saveds __asm
StatusGadgetDispatch(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
{
switch(msg -> MethodID)
{
/* Create new gadget. */
case OM_NEW:
return(NewStatusGadget(class,object,(struct opSet *)msg));
/* Set attributes. */
case OM_SET:
return(SetStatusGadget(class,object,(struct opSet *)msg));
/* Get attributes. */
case OM_GET:
return(GetStatusGadget(class,object,(struct opGet *)msg));
/* Dispose gadget. */
case OM_DISPOSE:
return(DelStatusGadget(class,object,msg));
/* Render the gadget. */
case GM_RENDER:
return(RenderStatusGadget(class,object,(struct gpRender *)msg));
/* Do nothing. */
case GM_HITTEST:
return(0);
/* Catchall... */
default:
return(DoSuperMethodA(class,object,msg));
}
}
/* FreeStatusGadgetClass():
*
* Free the private status gadget class.
*/
STATIC VOID
FreeStatusGadgetClass()
{
if(StatusGadgetClass)
{
FreeClass(StatusGadgetClass);
StatusGadgetClass = NULL;
}
}
/* NewStatusGadgetClass():
*
* Create a new status gadget class.
*/
STATIC BYTE
NewStatusGadgetClass()
{
/* Release the old instance. */
FreeStatusGadgetClass();
/* Localize the title texts. */
LocalizeString(ConfigFont,MSG_TERMAUX_STANDARD_FONT_TXT,MSG_TERMAUX_IBM_FONT_TXT);
LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_HANG_UP_TXT);
/* Create the class. */
if(StatusGadgetClass = MakeClass(NULL,GADGETCLASS,NULL,sizeof(struct StatusInfo),0))
{
/* Install the dispatcher. */
StatusGadgetClass -> cl_Dispatcher . h_Entry = (LONG (*)())StatusGadgetDispatch;
return(TRUE);
}
else
return(FALSE);
}
/* DeleteStatusGadget(struct Gadget *Gadget):
*
* Delete the status gadget.
*/
VOID
DeleteStatusGadget(struct Gadget *Gadget)
{
DisposeObject(Gadget);
FreeStatusGadgetClass();
}
/* CreateStatusGadget(LONG Width,LONG ID):
*
* Create the status gadget.
*/
struct Gadget *
CreateStatusGadget(LONG Width,LONG ID)
{
/* Create the new class. */
if(NewStatusGadgetClass())
{
struct Gadget *Gadget;
UBYTE Mode;
/* Determine the mode of operation. */
if(Config -> ScreenConfig -> StatusLine == STATUSLINE_COMPRESSED)
Mode = MODE_WB_COMPRESSED;
else
Mode = MODE_WB_NORMAL;
/* Create the new gadget. */
if(Gadget = NewObject(StatusGadgetClass,NULL,
GA_ID, ID,
GA_Left, 0,
GA_Width, Width,
SGA_Mode, Mode,
TAG_DONE))
return(Gadget);
else
FreeStatusGadgetClass();
}
return(NULL);
}
/* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
*
* Display information in the status line area.
*/
STATIC VOID __regargs
DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
{
/* What mode of operation is the status area in? */
switch(Mode)
{
/* Uses the status gadget class. */
case MODE_WB_NORMAL:
case MODE_WB_COMPRESSED:
SetGadgetAttrs(Object,Window,NULL,
SG_Status + Type,String,
TAG_DONE);
/* Kluge! */
if(Kick30)
RefreshGList(Object,Window,NULL,1);
break;
/* Compressed mode. */
case MODE_SCREEN_COMPRESSED:
{
struct RastPort *RPort = Object;
STATIC BYTE Offsets[8] =
{
0,
-1, /* Not supported */
26,
11,
40,
53,
61,
72
};
STATIC UBYTE Strings[8][20];
UBYTE LineBuffer[90];
LONG i,j,k,Width;
strcpy(Strings[Type],String);
strcpy(LineBuffer," · · · · · · ");
for(i = 0 ; i < 8 ; i++)
{
if(Offsets[i] >= 0)
{
j = strlen(Strings[i]);
for(k = 0 ; k < j ; k++)
LineBuffer[Offsets[i] + k] = Strings[i][k];
}
}
Width = TextLength(RPort,LineBuffer,80);
if(StatusLineWidth && StatusLineWidth != Width)
SetRast(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
StatusLineWidth = Width;
Move(RPort,(StatusWindow -> Width - Width) / 2,UserFontBase);
Text(RPort,LineBuffer,80);
}
break;
/* Normal mode. */
case MODE_SCREEN_NORMAL:
{
STATIC UBYTE Codes[8][2] =
{
STATUSBOX_STATUS_FONT, 0,
STATUSBOX_STATUS_FONT, 1,
STATUSBOX_PROTOCOL_TERMINAL, 0,
STATUSBOX_PROTOCOL_TERMINAL, 1,
STATUSBOX_RATE_PARAMETERS, 0,
STATUSBOX_RATE_PARAMETERS, 1,
STATUSBOX_TIME_ONLINE, 0,
STATUSBOX_TIME_ONLINE, 1
};
struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
SZ_PrintLine(Carrier -> RPort,Carrier -> BoxArray[Codes[Type][0]],Codes[Type][1],String);
}
break;
}
}
/* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
*
* Post an update message to the status display server.
*/
STATIC VOID __regargs
DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
{
struct UpdateMessage *Msg;
WORD Len = strlen(String) + 1;
/* Allocate enough space to hold both the string
* and the message.
*/
if(Msg = (struct UpdateMessage *)AllocVec(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
{
/* Fill in the message head. */
Msg -> VanillaMessage . mn_Length = sizeof(struct UpdateMessage) + Len;
/* Set up the name pointer. */
Msg -> VanillaMessage . mn_Node . ln_Name = (STRPTR)(Msg + 1);
/* Copy the string. */
strcpy(Msg -> VanillaMessage . mn_Node . ln_Name,String);
/* Fill in the remaining data. */
Msg -> Object = Object;
Msg -> Mode = Mode;
Msg -> Type = Type;
/* Post the message. */
PutMsg(StatusDisplayPort,(struct Message *)Msg);
}
}
/* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
*
* Update the information displayed in the status
* area.
*/
STATIC VOID __stdargs
UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
{
if(Object)
{
UBYTE MiniBuffer[50];
STRPTR *String;
LONG *Numeral;
va_list VarArgs;
va_start(VarArgs,Type);
String = (STRPTR *)VarArgs;
Numeral = (LONG *)VarArgs;
switch(Type)
{
case INFO_STATUS:
strcpy(MiniBuffer,ConfigStatus[Numeral[0]]);
strcat(MiniBuffer," ");
MiniBuffer[9] = 0;
DoInfo(Object,Mode,Type,MiniBuffer);
break;
case INFO_FONT:
if(Mode == MODE_SCREEN_NORMAL || Mode == MODE_WB_NORMAL)
DoInfo(Object,Mode,Type,ConfigFont[Numeral[0]]);
break;
case INFO_ONLINECOST:
strcpy(MiniBuffer,String[0]);
strcat(MiniBuffer," ");
MiniBuffer[8] = 0;
DoInfo(Object,Mode,INFO_ONLINETIME,MiniBuffer);
break;
case INFO_CURRENTTIME:
case INFO_ONLINETIME:
SPrintf(MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
DoInfo(Object,Mode,Type,MiniBuffer);
break;
case INFO_BAUDRATE:
if(LocaleBase)
SPrintf(MiniBuffer,"%lD ",Numeral[0]);
else
SPrintf(MiniBuffer,"%ld ",Numeral[0]);
MiniBuffer[7] = 0;
DoInfo(Object,Mode,Type,MiniBuffer);
break;
case INFO_PROTOCOL:
case INFO_EMULATION:
strcpy(MiniBuffer,String[0]);
strcat(MiniBuffer," ");
MiniBuffer[12] = 0;
DoInfo(Object,Mode,Type,MiniBuffer);
break;
case INFO_PARAMETERS:
if(Mode == MODE_SCREEN_COMPRESSED || Mode == MODE_WB_COMPRESSED)
{
STATIC UBYTE Parities[5] =
{
'N','E','O','M','S'
};
SPrintf(MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
}
else
SPrintf(MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
DoInfo(Object,Mode,Type,MiniBuffer);
break;
}
va_end(VarArgs);
}
}
/* Raise(UWORD Colour):
*
* Make an RGB value brighter.
*/
STATIC UWORD __inline
Raise(UWORD Colour)
{
UWORD R,G,B;
R = (Colour >> 8) + 4;
G = ((Colour >> 4) & 0xF) + 4;
B = ((Colour ) & 0xF) + 4;
if(R > 15)
R = 15;
if(G > 15)
G = 15;
if(B > 15)
B = 15;
return((UWORD)(R << 8 | G << 4 | B));
}
/* VisualBeep():
*
* Handle the visual part of the display beep.
*/
STATIC BYTE
VisualBeep(VOID)
{
struct UCopList *UserCopperList;
/* Create a user copper list. */
if(UserCopperList = (struct UCopList *)AllocMem(sizeof(struct UCopList),MEMF_ANY|MEMF_CLEAR))
{
/* Initialize for 35 commands. */
if(UCopperListInit(UserCopperList,1 + 16 + 1 + 16 + 1))
{
WORD i;
/* Wait until first line of window. */
CWAIT(UserCopperList,Window -> TopEdge,0);
/* Set the light colours. */
for(i = 0 ; i < 16 ; i++)
CMOVE(UserCopperList,custom . color[i],Raise(GetRGB4(Screen -> ViewPort . ColorMap,i)));
/* Wait until bottom of window. */
CWAIT(UserCopperList,Window -> TopEdge + Window -> Height - 1,0);
/* Set the standard colours. */
for(i = 0 ; i < 16 ; i++)
CMOVE(UserCopperList,custom . color[i],GetRGB4(Screen -> ViewPort . ColorMap,i));
/* Finish list. */
CEND(UserCopperList);
/* Install user copper list... */
Screen -> ViewPort . UCopIns = UserCopperList;
/* ...and display it. */
RethinkDisplay();
return(TRUE);
}
else
FreeMem(UserCopperList,sizeof(struct UCopList));
}
return(FALSE);
}
/* StatusDisplayServer(VOID):
*
* Yet another asynchronous background task to display
* some information.
*/
STATIC VOID __saveds
StatusDisplayServer(VOID)
{
/* Create the interface port. */
if(StatusDisplayPort = CreateMsgPort())
{
struct UpdateMessage *Msg;
ULONG Signals;
/* Ring back... */
Signal(StatusProcess,SIG_HANDSHAKE);
/* Wait for messages or termination signal. */
FOREVER
{
Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
/* Termination? */
if(Signals & SIG_KILL)
break;
/* Message arrival? */
if(Signals & PORTMASK(StatusDisplayPort))
{
/* Process all pending messages. */
while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
{
DoStatusInfo(Msg -> Object,Msg -> Mode,Msg -> Type,Msg -> VanillaMessage . mn_Node . ln_Name);
FreeVec(Msg);
}
}
}
/* Remove all pending messages. */
while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
FreeVec(Msg);
/* Remove the msgport. */
DeleteMsgPort(StatusDisplayPort);
}
/* Lock & quit... */
Forbid();
Signal(StatusProcess,SIG_HANDSHAKE);
RemTask(StatusDisplayTask = NULL);
}
/* StatusServer():
*
* Asynchronous process to continuosly display the current
* terminal settings.
*/
VOID __saveds
StatusServer()
{
STATIC struct timeval OnlineTime,
LastTime,
TempTime;
STATIC BYTE GotOnline = FALSE,
WasOnline = FALSE,
ShowPay = FALSE,
FlagBit = FALSE;
STATIC LONG SecCount = 0,
MinCount = 0,
BeepCount = 0;
struct TextBox *BoxArray[4],
*BoxList = NULL,
*Box;
struct RastPort *RPort;
APTR SomeObject;
struct ObjectCarrier Carrier;
struct timerequest *StatusTimeRequest;
struct MsgPort *StatusTimePort;
BYTE Background = FALSE,
FlashIt = FALSE,
SetColours = FALSE,
StandardColours = TRUE,
KeepGoing = TRUE,
Beeping = FALSE,
StatusMode = Config -> ScreenConfig -> StatusLine;
BYTE LastProtocol[40],
ProtocolBuffer[40],
LastEmulationName[40];
BYTE LastFont = -1,
LastEmulation = -1,
LastBitsPerChar = -1,
LastParity = -1,
LastStopBits = -1,
LastStatus = -1;
LONG LastBaud = -1;
LONG i,
ThisHour,
ThisMinute,
BoxCounter = 0,
FullWidth;
WORD ColumnLeft[4],
ColumnWidth[4],
Max,
Len;
BYTE AllFine = TRUE;
UBYTE Mode;
StatusLineWidth = 0;
LastProtocol[0] = 0;
LastEmulationName[0] = 0;
LocalizeString(ConfigFont,MSG_TERMAUX_STANDARD_FONT_TXT,MSG_TERMAUX_IBM_FONT_TXT);
LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
LocalizeString(ConfigStatus,MSG_TERMAUX_READY_TXT,MSG_TERMAUX_HANG_UP_TXT);
if(StatusWindow)
{
RPort = StatusWindow -> RPort;
/* Render the information. */
SZ_SizeSetup(Screen,&UserFont,TRUE);
if(StatusMode == STATUSLINE_COMPRESSED)
{
StatusOffset = (Screen -> Width - 80 * UserFontWidth) / 2;
SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
RectFill(RPort,0,0,StatusWindow -> Width - 1,StatusWindow -> Height - 1);
SetAPen(RPort,0);
SetBPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
}
else
{
SetAPen(RPort,DrawInfo -> dri_Pens[TEXTPEN]);
SetBPen(RPort,0);
/* Draw a separating line. */
Move(RPort,0,0);
Draw(RPort,StatusWindow -> Width - 1,0);
ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
Max = 0;
for(i = 0 ; ConfigStatus[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigStatus[i]))) > Max)
Max = Len;
}
for(i = 0 ; ConfigFont[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigFont[i]))) > Max)
Max = Len;
}
ColumnWidth[0] = Max;
Max = SZ_BoxWidth(12);
for(i = 0 ; ConfigEmulation[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
Max = Len;
}
ColumnWidth[1] = Max;
Max = SZ_BoxWidth(10);
for(i = 0 ; ConfigParity[i] ; i++)
{
if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
Max = Len;
}
ColumnWidth[2] = Max;
ColumnWidth[3] = SZ_BoxWidth(8);
FullWidth = 0;
for(i = 0 ; i < 4 ; i++)
FullWidth += ColumnWidth[i] + ColumnLeft[i];
FullWidth += 3 * InterWidth;
if(FullWidth > Screen -> Width)
SZ_SetLeftEdge(ColumnLeft[0]);
else
SZ_SetLeftEdge((Screen -> Width - FullWidth) / 2 + ColumnLeft[0]);
SZ_SetAbsoluteTop(2);
SZ_SetTopEdge(2);
SZ_SetWidth(ColumnWidth[0]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
SZ_SetWidth(ColumnWidth[1]);
SZ_AddLeftOffset(ColumnLeft[1]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
SZ_SetWidth(ColumnWidth[2]);
SZ_AddLeftOffset(ColumnLeft[2]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
SZ_SetWidth(ColumnWidth[3]);
SZ_AddLeftOffset(ColumnLeft[3]);
BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
if(!Box)
AllFine = FALSE;
else
SZ_DrawBoxes(RPort,BoxList);
}
}
else
{
if(Config -> ScreenConfig -> UseWorkbench && StatusGadget)
AllFine = TRUE;
}
/* Everything fine so far? */
if(AllFine)
{
Forbid();
/* Create the display server task. */
if(StatusDisplayTask = CreateTask("term status display task",5,StatusDisplayServer,4000))
{
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
}
Permit();
}
/* Is the display server task up and running? */
if(StatusDisplayTask)
{
/* Create a timer device request. */
if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
{
if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
{
if(!OpenDevice(TIMERNAME,UNIT_VBLANK,StatusTimeRequest,0))
{
/* Signal our father process
* that we're running.
*/
Signal(ThisProcess,SIG_HANDSHAKE);
if(StatusWindow)
{
if(StatusMode == STATUSLINE_COMPRESSED)
{
Mode = MODE_SCREEN_COMPRESSED;
SomeObject = RPort;
}
else
{
Mode = MODE_SCREEN_NORMAL;
Carrier . RPort = RPort;
Carrier . BoxArray = BoxArray;
SomeObject = &Carrier;
}
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
}
else
{
if(StatusGadget)
{
SomeObject = StatusGadget;
if(StatusMode == STATUSLINE_COMPRESSED)
Mode = MODE_WB_COMPRESSED;
else
Mode = MODE_WB_NORMAL;
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
}
else
SomeObject = NULL;
}
/* Keep on displaying. */
while(KeepGoing)
{
/* Are we to quit? */
if(CheckSignal(SIG_KILL))
KeepGoing = FALSE;
/* Get the current time. */
StatusTimeRequest -> tr_node . io_Command = TR_GETSYSTIME;
DoIO(StatusTimeRequest);
/* A connection has just
* been established.
*/
if(Online && !GotOnline)
{
OnlineTime = StatusTimeRequest -> tr_time;
/* Add up connection time. */
if(OnlinePlus)
{
struct timeval GetBack;
GetBack . tv_secs = (OnlinePlus / 6) * 60 + (OnlinePlus % 6) * 10;
GetBack . tv_micro = 0;
OnlinePlus = 0;
SubTime(&OnlineTime,&GetBack);
}
GotOnline = TRUE;
SecCount = 0;
FlagBit = FALSE;
}
/* Print the current time. */
ThisHour = (StatusTimeRequest -> tr_time . tv_secs % 86400) / 3600;
ThisMinute = (StatusTimeRequest -> tr_time . tv_secs % 3600) / 60;
UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,StatusTimeRequest -> tr_time . tv_secs % 60);
/* Handle routine checkup actions. */
if(!(SecCount & 1))
Signal(ThisProcess,SIG_CHECK);
if(Online)
{
WasOnline = TRUE;
if(ChosenEntry)
{
if(!(ThisMinute % 10) && !(StatusTimeRequest -> tr_time . tv_secs % 60))
{
ChosenInUse = TRUE;
SelectTime(ChosenEntry);
ChosenInUse = FALSE;
}
if(!CurrentPay)
CurrentPay = PayPerUnit[DT_FIRST_UNIT];
FlagBit ^= TRUE;
if(!FlagBit)
{
if(SecPerUnit[WhichUnit] && SecCount == SecPerUnit[WhichUnit])
{
SecCount = 0;
WhichUnit = DT_NEXT_UNIT;
CurrentPay += PayPerUnit[DT_NEXT_UNIT];
}
SecCount++;
}
}
/* Show the time
* we have been online
* yet.
*/
TempTime = StatusTimeRequest -> tr_time;
SubTime(&TempTime,&OnlineTime);
if(StatusTimeRequest -> tr_time . tv_secs != LastTime . tv_secs)
{
LastTime = StatusTimeRequest -> tr_time;
switch(Config -> ScreenConfig -> TimeMode)
{
case ONLINETIME_TIME: ShowPay = FALSE;
break;
case ONLINETIME_COST: ShowPay = TRUE;
break;
case ONLINETIME_BOTH: if(TempTime . tv_secs && !(TempTime . tv_secs % 5))
ShowPay ^= TRUE;
break;
}
if(ShowPay && ChosenEntry)
UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,CreateSum(CurrentPay,FALSE));
else
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
OnlineMinutes = TempTime . tv_secs / 60;
}
}
else
{
if(WasOnline)
{
WasOnline = FALSE;
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(TempTime . tv_secs % 86400) / 3600,(TempTime . tv_secs % 3600) / 60,TempTime . tv_secs % 60);
}
if(GotOnline)
GotOnline = FALSE;
}
/* Take care of the visual beep
* if enabled.
*/
if(Beeping)
{
if(!(BeepCount--))
{
Beeping = FALSE;
/* Remove the copper list. */
FreeVPortCopLists(&Screen -> ViewPort);
/* Really remove it. */
RemakeDisplay();
/* Clear the signal bit. */
ClrSignal(SIG_BELL);
}
}
/* Are we to show a visual beep? */
if(CheckSignal(SIG_BELL))
{
if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
DisplayBeep(Window -> WScreen);
else
{
if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
{
if(VisualBeep())
{
Beeping = TRUE;
BeepCount = 1;
}
}
}
}
/* Display the current terminal
* status.
*/
if(LastStatus != Status)
UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = Status);
/* Show the current transfer
* protocol.
*/
if(strcmp(LastProtocol,FilePart(Config -> FileConfig -> ProtocolFileName)))
{
strcpy(LastProtocol,FilePart(Config -> FileConfig -> ProtocolFileName));
if((Len = strlen(LastProtocol)) > 3)
{
strcpy(ProtocolBuffer,&LastProtocol[3]);
for(i = 0 ; i < Len - 3 ; i++)
{
if(ProtocolBuffer[i] == '.')
{
ProtocolBuffer[i] = 0;
break;
}
}
UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,ProtocolBuffer);
}
}
/* Show the current baud
* rate.
*/
if(LastBaud != Config -> SerialConfig -> BaudRate)
UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config -> SerialConfig -> BaudRate);
/* Show the current
* terminal font.
*/
if(LastFont != Config -> TerminalConfig -> FontMode)
{
LastFont = Config -> TerminalConfig -> FontMode;
UpdateInfo(SomeObject,Mode,INFO_FONT,LastFont != FONT_STANDARD);
}
/* Show the current terminal
* emulation.
*/
if(LastEmulation != Config -> TerminalConfig -> EmulationMode || (Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
{
LastEmulation = Config -> TerminalConfig -> EmulationMode;
if(Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
{
UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
strcpy(LastEmulationName,EmulationName);
}
else
UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
}
/* Show the current serial
* parameters (parity, etc).
*/
if(LastBitsPerChar != Config -> SerialConfig -> BitsPerChar || LastParity != Config -> SerialConfig -> Parity || LastStopBits != Config -> SerialConfig -> StopBits)
{
LastBitsPerChar = Config -> SerialConfig -> BitsPerChar;
LastParity = Config -> SerialConfig -> Parity;
LastStopBits = Config -> SerialConfig -> StopBits;
UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
}
/* Wait another half a second. */
if(KeepGoing)
{
ULONG Mask;
StatusTimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
StatusTimeRequest -> tr_time . tv_secs = 0;
StatusTimeRequest -> tr_time . tv_micro = MILLION / 2;
SendIO(StatusTimeRequest);
FOREVER
{
Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort));
if(Mask & SIG_BELL)
{
if(Config -> TerminalConfig -> BellMode == BELL_SYSTEM)
DisplayBeep(Window -> WScreen);
else
{
if(Screen && !Config -> ScreenConfig -> UseWorkbench && !Beeping && (Config -> TerminalConfig -> BellMode == BELL_VISIBLE || Config -> TerminalConfig -> BellMode == BELL_BOTH))
{
if(VisualBeep())
{
Beeping = TRUE;
BeepCount = 1;
}
}
}
}
if(Mask & PORTMASK(StatusTimePort))
{
WaitIO(StatusTimeRequest);
break;
}
}
/* Count up to a minute. */
if(MinCount++ == 120)
{
MinCount = 0;
/* Time limit present? */
if(LimitCount > 0)
LimitCount--;
/* Limit reached? */
if(!LimitCount)
Signal(ThisProcess,SIG_CHECK);
}
}
/* Make the colours blink. */
if(Screen && !Config -> ScreenConfig -> UseWorkbench)
{
if(Screen == IntuitionBase -> FirstScreen)
{
/* No main screen window active? */
if(StatusWindow)
{
if(!(Window -> Flags & WFLG_WINDOWACTIVE) && !(StatusWindow -> Flags & WFLG_WINDOWACTIVE))
StandardColours = TRUE;
}
else
{
if(!(Window -> Flags & WFLG_WINDOWACTIVE))
StandardColours = TRUE;
}
/* Menu button pressed or window disabled? */
if(Window -> Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
StandardColours = TRUE;
/* User is currently dragging the
* mouse in order to mark something
* on the screen?
*/
if(Marking)
StandardColours = TRUE;
Background = FALSE;
}
else
{
if(!Background)
StandardColours = TRUE;
Background = TRUE;
}
if(StandardColours)
{
if(!SetColours)
{
LoadRGB4(VPort,NormalColours,PaletteSize);
SetColours = TRUE;
}
StandardColours = FlashIt = FALSE;
}
else
{
/* Are we to flash the display? */
if(Config -> ScreenConfig -> Blinking)
{
if(Screen == IntuitionBase -> FirstScreen)
{
if(FlashIt)
{
LoadRGB4(VPort,BlinkColours,PaletteSize);
SetColours = FALSE;
}
else
{
LoadRGB4(VPort,NormalColours,PaletteSize);
SetColours = TRUE;
}
}
FlashIt ^= TRUE;
}
}
}
}
CloseDevice(StatusTimeRequest);
}
DeleteIORequest(StatusTimeRequest);
}
DeleteMsgPort(StatusTimePort);
}
if(StatusDisplayTask)
{
Forbid();
Signal(StatusDisplayTask,SIG_KILL);
ClrSignal(SIG_HANDSHAKE);
Wait(SIG_HANDSHAKE);
Permit();
}
if(BoxList)
SZ_FreeBoxes(BoxList);
}
/* Signal the father process that we're done
* and quietly remove ourselves.
*/
Forbid();
Signal(ThisProcess,SIG_HANDSHAKE);
StatusProcess = NULL;
}